<template>
    <div id="ArticleListPage">
        <el-row :gutter="20">
            <el-col :span="3"></el-col>
            <el-col :span="15">
                <el-card shadow="never">
                    <div class="search-container">
                        <!-- 搜索输入框和按钮 -->
                        <div class="search-bar">
                            <el-input
                                    v-model="searchParams.searchText"
                                    placeholder="从海量文章中搜索"
                                    size="large"
                                    suffix-icon="Search"
                                    @keyup.enter="doSearch"
                                    class="input-with-select"
                            >
                                <template #append>
                                    <el-button @click="doSearch">搜索</el-button>
                                </template>
                            </el-input>
                        </div>

                        <div class="category-tag-container">
                            <!-- 分类标签 -->
                            <el-tabs v-model="selectedCategory" @tab-click="doSearch" >
                                <el-tab-pane label="全部" value="all" name="all"/>
                                <el-tab-pane
                                        v-for="category in categoryList"
                                        :key="category"
                                        :label="category"
                                        :name="category"
                                />
                            </el-tabs>

                            <!-- 标签选择 -->
                            <div class="tag-bar">
                                <span class="tag-label">标签：</span>
                                <el-checkbox-group v-model="selectedTagList" @change="doSearch">
                                    <el-checkbox
                                            v-for="tag in tagList"
                                            :key="tag"
                                            :label="tag"
                                            :value="tag"
                                            class="tag-item"
                                    />
                                </el-checkbox-group>
                            </div>
                        </div>
                    </div>
                </el-card>
                <el-card shadow="never" class="mt-5">
                    <div style="font-size: 20px;border-left: 5px solid #2fbd67;padding-left: 10px;height: 30px;line-height: 30px;margin-bottom: 20px">
                        最新文章
                    </div>
                    <div class="container" v-for="item in data.articleList">
                        <el-skeleton
                                :loading="loading"
                                animated
                                :rows="1"
                        >
                            <template #default>
                                <article-card
                                        :id="item.id"
                                        :avatar="item.user.avatarUrl"
                                        :author="item.user.userAccount"
                                        :user-id="item.userId"
                                        :title="item.title"
                                        :content="item.content"
                                        :cover="item.coverUrl"
                                        :date="item.createTime"
                                        :views="item.viewCount"
                                        :likes="item.likeCount"
                                />
                            </template>
                        </el-skeleton>
                    </div>
                    <div v-if="data.articleList.length === 0">
                        <el-empty :image-size="200" >

                        </el-empty>
                    </div>

                </el-card>
            </el-col>
            <el-col :span="4"></el-col>
        </el-row>
        <div
                v-if="isLoading"
                class="flex justify-center items-center py-8"
        >
            <div class="animate-spin rounded-full h-10 w-10 border-t-2 border-b-2 border-blue-500"></div>
            <span class="ml-3">加载中...</span>
        </div>

        <div
                v-if="error"
                class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mt-6"
        >
            <strong class="font-bold">加载失败!</strong>
            <span class="block sm:inline">{{ error }}</span>
            <button @click="retryFetch" class="ml-4 text-blue-500 hover:text-blue-700">重试</button>
        </div>
    </div>
</template>

<script setup>
import {onMounted, onUnmounted, reactive, ref} from 'vue'
import myAxios from "@/axios/axios.js"
import {ElMessage} from "element-plus"
import ArticleCard from "@/components/ArticleCard.vue"
import {Search} from "@element-plus/icons-vue";

const data = reactive({
    articleList: []
})

const loading = ref(true)
const isLoading = ref(false)
const error = ref(null)
const hasMore = ref(true)
const page = ref(1)

const selectedCategory = ref('all')
const categoryList = ref([])
const tagList = ref([])
const selectedTagList = ref([])

const searchParams = reactive({
    pageNum: page.value,
    pageSize: 10,
    sortField: "createTime",
    sortOrder: "descend",
    searchText: '',
    category: '',
    tags: ''
})
// 获取标签和分类
const fetchTagsAndCategories = async () => {
    try {
        const res = await myAxios.get("/article/tag_category")
        if (res.code === 0 && res.data) {
            const { tagList: fetchedTagList, categoryList: fetchedCategoryList } = res.data
            tagList.value = fetchedTagList
            categoryList.value = fetchedCategoryList
        }
    } catch (err) {
        handleError(err, "获取标签或分类失败")
    }
}
// 统一错误处理
const handleError = (err, message = "网络请求出错，请稍后重试") => {
    ElMessage.error(message)
    console.error(message, err)
}
// 执行搜索
const doSearch = async () => {
    // 重置搜索条件
    searchParams.pageNum = 1
    searchParams.category = selectedCategory.value === 'all' ? '' : selectedCategory.value
    searchParams.tags = selectedTagList.value.filter(tag => tagList.value.includes(tag))

    try {
        const res = await myAxios.post("/article/list/page/vo", searchParams)
        handleFetchResult(res)
    } catch (err) {
        handleError(err, "数据加载失败")
    }finally {
        loading.value = false
    }
}
// 加载更多数据
const fetchData = async () => {
    if (isLoading.value || !hasMore.value) return

    isLoading.value = true
    error.value = null

    try {
        const res = await myAxios.get("/article/list/page/vo/cache", { params: searchParams })
        handleFetchResult(res, true)
    } catch (err) {
        handleError(err, "数据加载失败")
    } finally {
        isLoading.value = false
        loading.value = false
    }
}
// 处理请求结果
const handleFetchResult = (res, append = false) => {
    if (res.code === 0 && res.data) {
        if (res.data.records.length < 10) {
            hasMore.value = false
        }

        if (append) {
            data.articleList = [...data.articleList, ...res.data.records]
        } else {
            data.articleList = res.data.records
        }

        page.value++
    } else {
        ElMessage.error("服务器返回异常")
    }
}
// 滚动事件处理函数
const handleScroll = () => {
    if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 300) {
        searchParams.pageNum = page.value
        fetchData()
    }
}
// 初始化和清理
onMounted(async () => {
    try {
        await fetchTagsAndCategories()
        await fetchData()
        window.addEventListener('scroll', handleScroll)
    } catch (err) {
        handleError(err)
    }
})
onUnmounted(() => {
    // 移除滚动监听器防止内存泄漏
    window.removeEventListener('scroll', handleScroll)
})
// 重试加载
// 重试加载
const retryFetch = () => {
    if (!hasMore.value && data.articleList.length % 10 !== 0) {
        page.value = Math.ceil(data.articleList.length / 10)
        hasMore.value = true
    }
    fetchData()
}
</script>

<style scoped>
#ArticleListPage {
    min-height: 100vh;
}

.search-container {
    padding: 16px;
}

.category-tag-container {
    margin: 0;
    padding: 0;
}
:deep(.input-with-select .el-input-group__append) {
    background-color: var(--el-color-primary) !important;
    color: white;
}
.tag-bar {
    display: flex;
    align-items: center;
    margin-top: 16px;
}

.tag-label {
    margin-right: 8px;
    color: #606266;
}

.tag-item {
    margin-right: 8px;
    margin-bottom: 8px;
}

.search-bar {
    max-width: 600px;
    margin: 20px auto;
}
</style>
